#include "Triangulo.h"

Triangulo::Triangulo(const Float &u, const Float &v, const Float &w, unsigned int precision)
	: u(precision), v(precision), w(precision)
{
	this->u = u;
	this->v = v;
	this->w = w;
	this->precision = precision;
}

Triangulo::Triangulo(const Triangulo &otro)
	: u(otro.precision), v(otro.precision), w(otro.precision)
{
	this->copiar(otro);
}

Triangulo& Triangulo::operator=(const Triangulo &otro)
{
	if(*this != otro)
	{
		this->copiar(otro);
	}
	
	return *this;
}

Float Triangulo::areaHeron() const
{
	Float s = (this->u + this->v + this->w) / Float(2.0, this->precision);
	Float x(s * (s - this->u) * (s - this->v) * (s - this->w));
	
	return x.raiz();
}

Float Triangulo::areaDiferenciasFaciales() const
{
	Float A = (this->u - this->v + this->w);
	A *= (this->w - this->u + this->v);
	A *= (this->v - this->w + this->u);
	A *= (this->u + this->v + this->w);

	return ( A.raiz() / Float(4.0, this->precision) );
}

Float Triangulo::areaDiferenciasFacialesRevisado() const
{
	Float A = this->calculoDeParentesis(this->u, this->v, this->w);
	A *= this->calculoDeParentesis(this->w, this->u, this->v);
	A *= this->calculoDeParentesis(this->v, this->w, this->u);
	A *= (this->u + this->v + this->w);
	
	return ( A.raiz() / Float(4.0, this->precision) );
}

bool Triangulo::operator==(const Triangulo & otro) const
{
	return this->u == otro.u
		&& this->v == otro.v
		&& this->w == otro.w
		&& this->precision == otro.precision;
}

bool Triangulo::operator!=(const Triangulo &otro) const
{
	return !(*this == otro);
}

void Triangulo::definirU(const Float &u)
{
	this->u = u;
}

void Triangulo::definirV(const Float &v)
{
	this->v = v;
}

void Triangulo::definirW(const Float &w)
{
	this->w = w;
}

const Float & Triangulo::obtenerU() const
{
	return this->u;
}

const Float & Triangulo::obtenerV() const
{
	return this->v;
}

const Float & Triangulo::obtenerW() const
{
	return this->w;
}

void Triangulo::copiar(const Triangulo &otro)
{
	this->u = otro.u;
	this->v = otro.v;
	this->w = otro.w;
	this->precision = otro.precision;
}

Float Triangulo::calculoDeParentesis(const Float &a, const Float &b, const Float &c) const
{
	Float res (Float::max(a, c) - b);
	res += Float::min(a, c);
	
	return res;
}

